﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterCtrl : MonoBehaviour
{
	private GridMove m_grid_move;

	private GameObject m_player;

	private Vector3 target_dir1, target_dir2;

	private Vector3 move_target;

	public static int int_type;

	private float state_duration;

	private float acc_duration;

	private Animator m_animator;

	private GameControl game_ctrl;

	Vector3 dif;
	enum STATE
	{
		NONE,
		NORMAL,
		SPEEDDOWN,
		DEAD
	}

	private STATE ghost_state = STATE.NONE;
	enum GHOST_TYPE
	{
		NONE,
		TRACER,     //追赶型
		AMBUSH,     //埋伏性
		PINCER,  //包围型
		RANDOM  //随机型

	}
	private GHOST_TYPE ghost_type = GHOST_TYPE.NONE;
	// Start is called before the first frame update
	void Start()
	{
		int_type = 0;
		m_grid_move = GetComponent<GridMove>();
		m_player = GameObject.FindWithTag("Player");
		target_dir1 = Vector3.zero;
		target_dir2 = Vector3.zero;
		ghost_state = STATE.NORMAL;
		game_ctrl = GameObject.FindWithTag("GameCtrl").GetComponent<GameControl>();
		m_animator = GetComponent<Animator>();
	}

	// Update is called once per frame
	void Update()
	{
		if (ghost_state == STATE.SPEEDDOWN)
		{
			state_duration += Time.deltaTime;
			if (state_duration >= 20)
			{
				ghost_state = STATE.NORMAL;
				m_grid_move.ChangeSpeed(1);
			}
		}
		if (Vector3.Distance(transform.position, m_player.transform.position) >= 5)
		{
			AcceleratedTrack();
		}
		else
		{
			m_grid_move.ChangeSpeed(1);
		}
	}

	public void SetType(int i)
	{
		if (i == 1)
			ghost_type = GHOST_TYPE.TRACER;
		else if (i == 2)
			ghost_type = GHOST_TYPE.AMBUSH;
		else if (i == 3)
			ghost_type = GHOST_TYPE.PINCER;
		else if (i == 4)
			ghost_type = GHOST_TYPE.RANDOM;

	}
	public void OnGrid(Vector3 newPos)
	{
		//if (ghost_state != STATE.NORMAL)
		//	return;
		switch (ghost_type)
		{
			case GHOST_TYPE.TRACER:
				Tracer(newPos);
				break;
			case GHOST_TYPE.AMBUSH:
				Ambush(newPos);
				break;
			case GHOST_TYPE.RANDOM:
				RandomAI(newPos);
				break;
			case GHOST_TYPE.PINCER:
				Pincer(newPos);
				break;
		}
	}


	private void Tracer(Vector3 newPos)
	{
		dif = m_player.transform.position - newPos;

		if (Mathf.Abs(dif.x) <= Mathf.Abs(dif.z))
		{
			target_dir1 = new Vector3(1, 0, 0) * Mathf.Sign(dif.x);
			target_dir2 = new Vector3(0, 0, 1) * Mathf.Sign(dif.z);
		}
		else
		{
			target_dir1 = new Vector3(0, 0, 1) * Mathf.Sign(dif.z);
			target_dir2 = new Vector3(1, 0, 0) * Mathf.Sign(dif.x);
		}
		move_target = DirectionChoice(target_dir1, target_dir2);

		if (move_target != Vector3.zero)
			m_grid_move.SetDirection(move_target);
		else
			m_grid_move.SetDirection(Vector3.zero);
	}

	private void Ambush(Vector3 newPos)
	{
		dif = m_player.GetComponent<GridMove>().GetForwardDis(1, int_type) - newPos;

		if (Mathf.Abs(dif.x) >= Mathf.Abs(dif.z))
		{
			target_dir1 = new Vector3(1, 0, 0) * Mathf.Sign(dif.x);
			target_dir2 = new Vector3(0, 0, 1) * Mathf.Sign(dif.z);
		}
		else
		{
			target_dir1 = new Vector3(0, 0, 1) * Mathf.Sign(dif.z);
			target_dir2 = new Vector3(1, 0, 0) * Mathf.Sign(dif.x);
		}
		move_target = DirectionChoice(target_dir1, target_dir2);

		if (move_target != Vector3.zero)
			m_grid_move.SetDirection(move_target);
		else
			m_grid_move.SetDirection(Vector3.zero);
	}

	private void Pincer(Vector3 newPos)
	{
		dif = m_player.GetComponent<GridMove>().GetForwardDis(-1, int_type) - newPos;

		if (Mathf.Abs(dif.x) >= Mathf.Abs(dif.z))
		{
			target_dir1 = new Vector3(1, 0, 0) * Mathf.Sign(dif.x);
			target_dir2 = new Vector3(0, 0, 1) * Mathf.Sign(dif.z);
		}
		else
		{
			target_dir1 = new Vector3(0, 0, 1) * Mathf.Sign(dif.z);
			target_dir2 = new Vector3(1, 0, 0) * Mathf.Sign(dif.x);
		}
		move_target = DirectionChoice(target_dir1, target_dir2);

		if (move_target != Vector3.zero)
			m_grid_move.SetDirection(move_target);
		else
			m_grid_move.SetDirection(Vector3.zero);
	}
	Vector3[] dirList = {
		new Vector3(1, 0, 0),
		new Vector3(-1, 0, 0),
		new Vector3(0, 0, 1),
		new Vector3(0, 0, -1),
	};
	int dirNum = 0;
	private void RandomAI(Vector3 newPos)
	{
		if (m_grid_move.WallCheck(m_grid_move.GetDirection()) || !m_grid_move.Is_Running())
		{
			if (dirNum % 2 == 0)
			{
				target_dir1 = dirList[Random.Range(0, 2)];
				target_dir2 = dirList[Random.Range(0, 2) + 2];
			}
			else
			{
				target_dir1 = dirList[Random.Range(0, 2) + 2];
				target_dir1 = dirList[Random.Range(0, 2)];
			}

			move_target = DirectionChoice(target_dir1, target_dir2);

			if (move_target != Vector3.zero)
				m_grid_move.SetDirection(move_target);
			else
				m_grid_move.SetDirection(Vector3.zero);

			dirNum++;
		}

	}

	private Vector3 DirectionChoice(Vector3 fistar, Vector3 sectar)
	{
		if (!m_grid_move.WallCheck(fistar) && m_grid_move.IsReverseDirection(fistar))
			return fistar;

		if (!m_grid_move.WallCheck(sectar) && m_grid_move.IsReverseDirection(sectar))
			return sectar;

		fistar *= -1.0f;
		sectar *= -1.0f;

		if (!m_grid_move.WallCheck(fistar) && m_grid_move.IsReverseDirection(fistar))
			return fistar;

		if (!m_grid_move.WallCheck(sectar) && m_grid_move.IsReverseDirection(sectar))
			return sectar;
		return Vector3.zero;
	}

	public void DecreaseSpeed()
	{
		ghost_state = STATE.SPEEDDOWN;
		state_duration = 0;
		m_grid_move.ChangeSpeed(0.5f);
	}

	public void AcceleratedTrack()
	{
		if (ghost_state == STATE.NORMAL)
			m_grid_move.ChangeSpeed(1.5f);
		else
			m_grid_move.ChangeSpeed(1f);
	}
	private Transform m_target;
	public void Attack(Transform other)
	{
		m_target = other;
		StartCoroutine(GhostAttack());
	}
	public IEnumerator GhostAttack()
	{
		yield return new WaitForSeconds(1f);
		m_player.GetComponent<PlayerControl>().DecreaseHp();
		game_ctrl.OnAttack();
		transform.LookAt(m_target.position);
		GameObject.Find("GameControllor").SendMessage("PlayerUnderAttack",0);
		yield return null;

		m_animator.SetTrigger("begin_attack");
		yield return new WaitForSeconds(1f);
		game_ctrl.EndAttack();
		this.transform.GetComponent<CharaAnimationMonster>().Normal();
	}

	public void UnderAttack()
	{
		m_animator.SetTrigger("begin_dead");
		ghost_state = STATE.DEAD;
		GameObject.Find("GameControllor").SendMessage("MonsterDead",0);
		Destroy(gameObject,1f);
	}

}
